package logic

import (
	"context"
	"fmt"

	"godco/internal/svc"
	"godco/internal/types"
	"regexp"

	rs "godco/internal/model/result"

	"github.com/zeromicro/go-zero/core/logx"
	//"github.com/tidwall/pretty"
)

type PushHookLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewPushHookLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PushHookLogic {
	return &PushHookLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func checkSignedOffBy(message string) bool {
	// match "Signed-off-by"
	re := regexp.MustCompile(`Signed-off-by:\s+\S+\s+<\S+@\S+\.\S+>`)
	return re.MatchString(message)
}

func getSignedOffBy(message string) (string, string, error) {
	// match "Signed-off-by" name and email
	re := regexp.MustCompile(`Signed-off-by:\s+(\S+)\s+<(\S+@\S+\.\S+)>`)

	// match
	matches := re.FindStringSubmatch(message)
	if matches == nil {
		return "", "", fmt.Errorf("no 'Signed-off-by' signature found")
	}

	//get name and email
	name := matches[1]
	email := matches[2]

	return name, email, nil
}

func (l *PushHookLogic) PushHook(req *types.PushHookRequest) (resp *types.PushHookResp, err error) {
	// todo: add your logic here and delete this line
	//l.Debugf("request: %v\n", *req)
	l.Debug(">>PushHook ENTER:\n")
	l.Debugf("处理仓库:%s", req.Repository.GitURL)
	l.Debugf("验证提交:%s", req.Commits[0].URL)
	l.Debugf("提交者:%s", req.Commits[0].Committer.Name)
	l.Debugf("commit message:%s", req.Commits[0].Message)
	l.Debug("开始验证DCO签名...")
	result := rs.DcoResult{}
	result.CID = req.Commits[0].ID
	result.Name = req.Commits[0].Committer.Name
	result.Email = req.Commits[0].Committer.Email
	result.Branch = req.Commits[0].URL
	result.Result = "fail"
	if checkSignedOffBy(req.Commits[0].Message) {
		l.Debug("ok, it contains Signed-off-by")
		name, email, err := getSignedOffBy(req.Commits[0].Message)
		if err != nil {
			l.Error("Error getSignedOffBy")
			l.Debug("未通过DCO验证")
		} else {
			l.Debugf("Signed-off-by name:%s", name)
			l.Debugf("Signed-off-by email:%s", email)

			if name == req.Commits[0].Author.Name && email == req.Commits[0].Author.Email {
				l.Debug("ok, dco check ok")
				l.Debug("通过DCO验证")
				result.Result = "ok"
			}
		}
	} else {
		l.Error("dco check error, not contains Signed-off-by")
		l.Debug("未通过DCO验证")
	}

	l.Debug("DCO验证结果入库")
	err = l.svcCtx.ResultModel.InsertOrUpdate(l.ctx, &result)
	if err != nil {
		l.Debug("DCO验证结果入库失败:" + err.Error())
	} else {
		l.Debug("DCO验证结果入库成功")
	}

	res := types.PushHookResp{Code: 0, Message: "success"}

	return &res, nil
}
